package com.doraz.orb.utils;

import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.*;

import android.util.Log;

import com.doraz.orb.structs.Computer;
import com.doraz.orb.structs.Group;
import com.doraz.orb.structs.OrbItem;
import com.doraz.orb.structs.OrbObject;
import com.doraz.orb.structs.SearchResult;

public class XMLUtils {

	public final static String TAG = "XMLUtils";
	private static DocumentBuilderFactory dbf = null;
	private static DocumentBuilder dbuilder = null;
	
	/**
	 * Initializes the DocumnentBuidlerFactory / DocumentBuilder
	 * 
	 * @throws Exception
	 */
	private static void init() throws Exception {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder dbuilder = dbf.newDocumentBuilder();
	}
	
	/**
	 * Parses the input stream, then closes it
	 * 
	 * @param in	the input stream
	 * @return		the document
	 */
	public static Document getDocument(InputStream in) {
		Document doc = null;
		try {
			if(dbf == null || dbuilder == null) {
				init();
			}
			
			//Parse the input Stream
			doc = dbuilder.parse(in);
		}
		catch(Exception e) {
			Log.w(TAG, "Error parsing input stream: "+e.getMessage());
		}
		finally {
			if(in != null) {
				try {
					in.close();
				}
				catch(Exception ie) {
					//Ignore
				}
			}
		}
		
		return doc;
	}
	
	/**
	 * Gets the text content of an Element
	 * 
	 * @param element	the element
	 * @return			the text (or empty String)
	 */
	public static String getText(Element element) {
		StringBuilder text = new StringBuilder();
		NodeList children = element.getChildNodes();
		for(int i = 0; i < children.getLength(); i++) {
			if(children.item(i).getNodeType() == Node.TEXT_NODE) {
				text.append(children.item(i).getNodeValue());
			}
		}
		return text.toString();
	}
	
	/**
	 * Parses a new Computer object
	 * 
	 * @param element	the status
	 * @return			a new computer
	 */
	public static Computer parseComputer(Element element) {
		Computer comp = null;
		int status = Computer.STATUS_OFFLINE;
		
		String onlStatus = element.getNodeValue();
		if(onlStatus.equals("ONLINE")) {
			status = Computer.STATUS_ONLINE;
		}
		else if(onlStatus.equals("SLEEPING")) {
			status = Computer.STATUS_SLEEPING;
		}
		else {
			status = Computer.STATUS_OFFLINE;
		}
		
		comp = new Computer(status);
		return comp;
	}
	
	/**
	 * Parses a SearchResult
	 * @param result
	 * @return
	 */
	public static SearchResult parseResult(Element result) {
		SearchResult results = new SearchResult(result.getAttribute("searchId"), new IntValidator().parseInt(result.getAttribute("groupCount")), new IntValidator().parseInt(result.getAttribute("itemCount")));
		NodeList children = result.getChildNodes();
		for(int i = 0; i < children.getLength(); i++) {
			if(children.item(i).getNodeType() == Node.ELEMENT_NODE) {
				Element el = (Element) children.item(i);
				if("group".equals(el.getTagName())) {
					results.addObject(parseGroup(el));
				}
				else if("item".equals(el.getTagName())) {
					results.addObject(parseItem(el));
				}
			}
		}
		
		return results;
	}
	
	/**
	 * Parses a new Group object
	 * 
	 * @param element	the group element
	 * @return			a new group
	 */
	public static Group parseGroup(Element element) {
		String searchId = element.getAttribute("searchId");
		String path = element.getAttribute("value");
		String title = element.getAttribute("title");
		int count = new IntValidator().parseInt(element.getAttribute("count"));
		return new Group(searchId,path,title,count);
	}
	
	/**
	 * Parses an OrbItem
	 * 
	 * @param element	the item element
	 * @return			a new OrbItem
	 */
	public static OrbItem parseItem(Element element) {
		OrbItem item = new OrbItem(element.getAttribute("orbMediumId"));
		
		NodeList fields = element.getChildNodes();
		for(int i = 0; i < fields.getLength(); i++) {
			if(fields.item(i).getNodeType() == Node.ELEMENT_NODE) {
				Element field = (Element) fields.item(i);
				String name = field.getAttribute("name");
				if("title".equals(name)) {
					item.setTitle(XMLUtils.getText(field));
				}
				else if("path".equals(name)) {
					String path = XMLUtils.getText(field);					
				}
			}
		}
		
		return item;
	}
}
